# CCN::Daemon.pm
# (c) 2007, Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

#
# Inspired by http://www.webreference.com/perl/tutorial/9/
# and the documentation for Tie::Syslog;
#

use strict; use warnings;

package CCN::Syslogger;
use base qw(CCN::Class);
use Sys::Syslog;

our $syslog_opened = 0;

sub initialize($)
{
    our $self = shift;
    my ($name) = @_;

    openlog $name, 'pid cons', 'daemon'
        or $self->die("Can start syslog: $!");

    # Force other classes to use Syslogger.
    $self->set_logger($self);

    $syslog_opened = 1;

    # Change SIG WARN
    $self->{sig_warn} = $SIG{__WARN__}
        if not exists $self->{sig_warn};

    $SIG{__WARN__} = sub {
        $self->warn(@_);
    };

    # Change CORE::GLOBAL::die
    # use subs qw(CORE::GLOBAL::die);
    # $self->{core_global_die} = *CORE::GLOBAL::die
    #     if not exists $self->{core_global_die};
    # *{CORE::GLOBAL::die} = sub {
    #     syslog 'err', @_;
    #     CORE::die(@_);
    # };
    $self->{sig_die} = $SIG{__DIE__}
        if not exists $self->{sig_die};

    $SIG{__DIE__} = sub {
        my $in_eval = defined $^S && $^S;
        # eval can be used as try .. catch. So let's differentiate.
        if($in_eval)
        {
            $self->warn(@_);
        }
        else
        {
            $self->die(@_);
        }
    };

}

sub DESTROY
{
    my $self = shift;

    $SIG{__WARN__} = $self->{sig_warn}
        if exists $self->{sig_warn};

    $SIG{__DIE__} = $self->{sig_die}
        if exists $self->{sig_die};

    *CORE::GLOBAL::die = $self->{core_global_die}
        if exists $self->{core_global_die};

    $self->set_logger(undef);
    closelog();
    $syslog_opened = 0;
}

sub log_for
{
    my $self = shift;
    my $level = shift;
    syslog $level, '%s', join(' ',@_);
}

1;